import json

from flask import redirect, request, url_for, render_template, flash
from flask_login import login_user, logout_user, current_user

from ..models import UserInfo, OAuth
from . import social
from ..auth import douban, qq, weibo
from ..main import main
from .. import db


@social.route('/social', methods=['GET'])
def social_redirict():
    # return 'hello %r' % request.args['connect_type']
    if request.args['connect_type'] == 'douban':
        return redirect(douban.authorize_url)
    elif request.args['connect_type'] == 'qq':
        return redirect(qq.authorize_url)
    elif request.args['connect_type'] == 'weibo':
        return redirect(weibo.authorize_url)
    else:
        return '这个还没准备好'


@social.route('/social/bind/douban', methods=['GET'])
def bind_douban():
    code = request.args['code']
    response = douban.get_token_response(code)
    access_token = response.get('access_token')
    uid = response.get('douban_user_id')

    oauth = OAuth.query.filter(OAuth.oauth_name=='douban',
                               OAuth.oauth_id==uid).first()

    if oauth:
        # 存在 OAuth 记录
        if current_user.is_anonymous():
            # 匿名用户，说明现在是登陆操作
            user = UserInfo.query.get(oauth.user_id)
            if user:
                # 存在用户
                login_user(user, True)
                flash('欢迎回来')
                return redirect(url_for('main.index'))
        else:
            # 已经有用户登录，说明是绑定操作，存在异常
            binded_user = UserInfo.query.get(oauth.user_id)
            return redirect(url_for('social.bind_failed', reason='binded', binded_name=binded_user.screenname))
    else:
        # 若不存在则检查是否已经登陆来判断是登陆还是绑定
        user = current_user
        user_is_new = False
        if user.is_anonymous():
            # new user, need create
            user_info = douban.get_user_info(access_token)
            user_info = json.loads(user_info)
            user_is_new = True
            user = UserInfo()
            user.screenname = user_info.get('name') or 'new'
            user.desc = user_info.get('desc') or ''
            db.session.add(user)
            db.session.commit()
        new_oauth = OAuth()
        new_oauth.oauth_name = 'douban'
        new_oauth.oauth_id = uid
        new_oauth.oauth_access_token = access_token
        new_oauth.user_id = user.id
        db.session.add(new_oauth)
        db.session.commit()
        login_user(user, True)
        if user_is_new:
            flash('注册成功')
        else:
            flash('绑定成功')
        return redirect(url_for('account.basic'))
    return 'douban failed'


@social.route('/social/bind/qq', methods=['GET'])
def bind_qq():
    code = request.args['code']
    access_token = qq.get_token(code)
    access_token = access_token.token
    openid = qq.get_openid(access_token)
    # userinfo = qq.get_user_info(access_token.token, openid)

    oauth = OAuth.query.filter(OAuth.oauth_name=='qq',
                               OAuth.oauth_id==openid).first()
    if oauth:
        # 存在 OAuth 记录
        if current_user.is_anonymous():
            # 匿名用户，说明现在是登陆操作
            user = UserInfo.query.get(oauth.user_id)
            if user:
                # 存在用户
                login_user(user, True)
                flash('欢迎回来')
                return redirect(url_for('main.index'))
        else:
            # 已经有用户登录，说明是绑定操作，存在异常
            binded_user = UserInfo.query.get(oauth.user_id)
            return redirect(url_for('social.bind_failed', reason='binded', binded_name=binded_user.screenname))
    else:
        user = current_user
        user_is_new = False
        if user.is_anonymous():
            # new user, need create
            user_info = qq.get_user_info(access_token, openid)
            user_info = json.loads(user_info)
            user_is_new = True
            user = UserInfo()
            user.screenname = user_info.get('nickname') or 'new'
            user.desc = ''
            db.session.add(user)
            db.session.commit()
        new_oauth = OAuth()
        new_oauth.oauth_name = 'qq'
        new_oauth.oauth_id = openid
        new_oauth.oauth_access_token = access_token
        new_oauth.user_id = user.id
        db.session.add(new_oauth)
        db.session.commit()
        login_user(user, True)
        if user_is_new:
            flash('注册成功')
        else:
            flash('绑定成功')
        return redirect(url_for('account.basic'))
    return 'qq failed'


@social.route('/social/bind/weibo', methods=['GET'])
def bind_weibo():
    code = request.args['code']
    response = weibo.get_token_response(code)
    access_token = response.get('access_token')
    uid = response.get('uid')
    # user_info = weibo.get_user_info(access_token, uid)

    oauth = OAuth.query.filter(OAuth.oauth_name=='weibo',
                               OAuth.oauth_id==uid).first()
    if oauth:
        # 存在 OAuth 记录
        if current_user.is_anonymous():
            # 匿名用户，说明现在是登陆操作
            user = UserInfo.query.get(oauth.user_id)
            if user:
                # 存在用户
                login_user(user, True)
                flash('欢迎回来')
                return redirect(url_for('main.index'))
        else:
            # 已经有用户登录，说明是绑定操作，存在异常
            binded_user = UserInfo.query.get(oauth.user_id)
            return redirect(url_for('social.bind_failed', reason='binded', binded_name=binded_user.screenname))
    else:
        # 若不存在则检查是否已经登陆来判断是登陆还是绑定
        user = current_user
        user_is_new = False
        if user.is_anonymous():
            # new user, need create
            user_info = weibo.get_user_info(access_token, uid)
            user_info = json.loads(user_info)
            user_is_new = True
            user = UserInfo()
            user.screenname = user_info.get('screen_name') or 'new'
            user.desc = user_info.get('description') or ''
            db.session.add(user)
            db.session.commit()
        new_oauth = OAuth()
        new_oauth.oauth_name = 'weibo'
        new_oauth.oauth_id = uid
        new_oauth.oauth_access_token = access_token
        new_oauth.user_id = user.id
        db.session.add(new_oauth)
        db.session.commit()
        login_user(user, True)
        if user_is_new:
            flash('注册成功')
        else:
            flash('绑定成功')
        return redirect(url_for('account.basic'))
    # return 'response: %s, uid %r' % (access_token, uid)
    return 'weibo failed'


@social.route('/social/bind/failed', methods=['GET'])
def bind_failed():
    reason = request.args.get('reason')
    binded_name = request.args.get('binded_name')
    if reason == 'binded':
        msg = '账号已经绑定了用户（%s）' % (binded_name)
    return render_template('social/failed.html', msg=msg)


@social.route('/social/unbind/<oauth_name>', methods=['GET'])
def unbind(oauth_name):
    if not current_user.is_anonymous():
        # 如果当前有用户在登陆
        # 检查用户的绑定数量
        oauth_count = OAuth.query.filter_by(user_id=current_user.id).count()
        if oauth_count > 1:
            # 删除 OAuth 记录
            oauth = OAuth.query.filter_by(user_id=current_user.id,
                                          oauth_name=oauth_name).first()
            db.session.delete(oauth)
            db.session.commit()
        elif oauth_count == 1:
            # 登出、删除用户、删除 OAuth 记录
            oauth = OAuth.query.filter_by(user_id=current_user.id,
                                           oauth_name=oauth_name).first()
            # 为了用户数据的保存，不删除
            # user = UserInfo.query.filter_by(id=current_user.id).first()
            logout_user()
            db.session.delete(oauth)
            # db.session.delete(user)
            db.session.commit()
    flash('解绑成功')
    return redirect(url_for('main.index'))
